import * as os from 'os';
import * as fs from 'fs/promises';
import * as path from 'path';
import { EventEmitter } from 'events';
import pidusage from 'pidusage';
import diskusage from 'diskusage';
import logger from './utils/logger';

// 监控配置接口
interface MonitorConfig {
    enabled: boolean;
    interval: number;
    metrics: {
        cpu: MetricConfig;
        memory: MetricConfig;
        disk: MetricConfig;
        processes: MetricConfig;
    };
    autoSave: boolean;
    historySize: number;
}

// 指标配置接口
interface MetricConfig {
    enabled: boolean;
    threshold: number;
    action: 'notify' | 'alert' | 'auto_fix' | 'none';
}

// 系统指标接口
interface SystemMetrics {
    timestamp: number;
    cpu: {
        usage: number;
        cores: number;
        loadAvg: number[];
        temperature?: number; // CPU温度（如果可用）
    };
    memory: {
        total: number;
        free: number;
        used: number;
        usage: number;
        swap?: {
            total: number;
            free: number;
            used: number;
        };
    };
    disk: {
        total: number;
        free: number;
        used: number;
        usage: number;
        io?: {
            read: number;
            write: number;
        };
    };
    processes: {
        count: number;
        active: number;
        list?: Array<{
            pid: number;
            name: string;
            cpu: number;
            memory: number;
        }>;
    };
    battery?: {
        level: number;
        charging: boolean;
        timeRemaining?: number;
    };
}

/**
 * 系统监控类
 * 负责收集系统指标并在超过阈值时触发事件
 */
export class SystemMonitor extends EventEmitter {
    private config: MonitorConfig;
    private interval: NodeJS.Timeout | null = null;
    private running: boolean = false;
    private lastMetrics: SystemMetrics | null = null;
    private metricsHistory: SystemMetrics[] = [];
    private configPath: string;
    private historyPath: string;

    /**
     * 创建系统监控实例
     * @param configPath 配置文件路径
     */
    constructor(configPath: string) {
        super();
        this.configPath = configPath;
        this.historyPath = path.join(path.dirname(configPath), 'metrics-history.json');

        // 默认配置
        this.config = {
            enabled: true,
            interval: 60, // 60秒
            metrics: {
                cpu: {
                    enabled: true,
                    threshold: 80, // 80%
                    action: 'notify'
                },
                memory: {
                    enabled: true,
                    threshold: 85, // 85%
                    action: 'notify'
                },
                disk: {
                    enabled: true,
                    threshold: 90, // 90%
                    action: 'notify'
                },
                processes: {
                    enabled: true,
                    threshold: 0,
                    action: 'none'
                }
            },
            autoSave: true,
            historySize: 100 // 保存最近100条记录
        };

        this.loadConfig().catch(error => {
            logger.error('加载配置失败，使用默认配置', { error });
        });

        this.loadHistory().catch(error => {
            logger.error('加载历史数据失败', { error });
        });
    }

    /**
     * 加载配置文件
     */
    private async loadConfig(): Promise<void> {
        try {
            const configData = await fs.readFile(this.configPath, 'utf8');
            const config = JSON.parse(configData);

            if (config.system) {
                this.config.enabled = config.system.enabled ?? this.config.enabled;
                this.config.interval = config.system.interval ?? this.config.interval;
                this.config.autoSave = config.system.autoSave ?? this.config.autoSave;
                this.config.historySize = config.system.historySize ?? this.config.historySize;

                if (config.system.metrics) {
                    // 合并 CPU 配置
                    if (config.system.metrics.cpu) {
                        this.config.metrics.cpu = {
                            ...this.config.metrics.cpu,
                            ...config.system.metrics.cpu
                        };
                    }

                    // 合并内存配置
                    if (config.system.metrics.memory) {
                        this.config.metrics.memory = {
                            ...this.config.metrics.memory,
                            ...config.system.metrics.memory
                        };
                    }

                    // 合并磁盘配置
                    if (config.system.metrics.disk) {
                        this.config.metrics.disk = {
                            ...this.config.metrics.disk,
                            ...config.system.metrics.disk
                        };
                    }

                    // 合并进程配置
                    if (config.system.metrics.processes) {
                        this.config.metrics.processes = {
                            ...this.config.metrics.processes,
                            ...config.system.metrics.processes
                        };
                    }
                }
            }

            logger.info('已加载监控配置', { config: this.config });
        } catch (error) {
            if (error.code !== 'ENOENT') {
                logger.error('读取配置文件失败', { error });
            } else {
                logger.warn('配置文件不存在，使用默认配置');
                // 创建默认配置文件
                await this.saveConfig();
            }
        }
    }

    /**
     * 保存配置到文件
     */
    private async saveConfig(): Promise<void> {
        try {
            // 确保目录存在
            await fs.mkdir(path.dirname(this.configPath), { recursive: true });

            // 写入配置文件
            await fs.writeFile(
                this.configPath,
                JSON.stringify({ system: this.config }, null, 2),
                'utf8'
            );

            logger.info('已保存监控配置');
        } catch (error) {
            logger.error('保存配置文件失败', { error });
        }
    }

    /**
     * 加载历史指标数据
     */
    private async loadHistory(): Promise<void> {
        try {
            const historyData = await fs.readFile(this.historyPath, 'utf8');
            this.metricsHistory = JSON.parse(historyData);
            logger.info(`已加载 ${this.metricsHistory.length} 条历史指标数据`);
        } catch (error) {
            if (error.code !== 'ENOENT') {
                logger.error('读取历史数据失败', { error });
            } else {
                logger.info('历史数据文件不存在，将创建新文件');
                this.metricsHistory = [];
            }
        }
    }

    /**
     * 保存历史指标数据
     */
    private async saveHistory(): Promise<void> {
        if (!this.config.autoSave) return;

        try {
            // 确保目录存在
            await fs.mkdir(path.dirname(this.historyPath), { recursive: true });

            // 限制历史记录数量
            if (this.metricsHistory.length > this.config.historySize) {
                this.metricsHistory = this.metricsHistory.slice(-this.config.historySize);
            }

            // 写入历史数据文件
            await fs.writeFile(
                this.historyPath,
                JSON.stringify(this.metricsHistory, null, 2),
                'utf8'
            );

            logger.debug(`已保存 ${this.metricsHistory.length} 条历史指标数据`);
        } catch (error) {
            logger.error('保存历史数据失败', { error });
        }
    }

    /**
     * 启动监控
     */
    async start(): Promise<void> {
        if (this.running) {
            logger.warn('监控已经在运行中');
            return;
        }

        if (!this.config.enabled) {
            logger.warn('监控已禁用，无法启动');
            return;
        }

        try {
            // 立即收集一次指标
            await this.collectMetrics();

            // 设置定时器定期收集指标
            this.interval = setInterval(async () => {
                try {
                    await this.collectMetrics();
                } catch (error) {
                    logger.error('收集指标失败', { error });
                    this.emit('error', error);
                }
            }, this.config.interval * 1000);

            this.running = true;
            logger.info('监控已启动', { interval: this.config.interval });

            // 确保定时器不会阻止进程退出
            if (this.interval.unref) {
                this.interval.unref();
            }
        } catch (error) {
            logger.error('启动监控失败', { error });
            throw error;
        }
    }

    /**
     * 停止监控
     */
    async stop(): Promise<void> {
        if (!this.running) {
            logger.warn('监控未在运行');
            return;
        }

        if (this.interval) {
            clearInterval(this.interval);
            this.interval = null;
        }

        // 保存历史数据
        await this.saveHistory();

        this.running = false;
        logger.info('监控已停止');
    }

    /**
     * 收集系统指标
     */
    private async collectMetrics(): Promise<void> {
        try {
            const metrics = await this.getSystemMetrics();
            this.lastMetrics = metrics;

            // 添加到历史记录
            this.metricsHistory.push(metrics);

            // 如果历史记录过多，删除旧记录
            if (this.metricsHistory.length > this.config.historySize) {
                this.metricsHistory.shift();
            }

            // 发出指标事件
            this.emit('metrics', metrics);

            // 检查阈值
            this.checkThresholds(metrics);

            // 定期保存历史数据
            if (this.metricsHistory.length % 10 === 0) {
                await this.saveHistory();
            }

            logger.debug('已收集系统指标', { metrics });
        } catch (error) {
            logger.error('收集系统指标失败', { error });
            throw error;
        }
    }

    /**
     * 获取系统指标
     */
    private async getSystemMetrics(): Promise<SystemMetrics> {
        // CPU 使用率
        const cpuUsage = await this.getCpuUsage();

        // 内存使用情况
        const totalMem = os.totalmem();
        const freeMem = os.freemem();
        const usedMem = totalMem - freeMem;
        const memUsage = (usedMem / totalMem) * 100;

        // 磁盘使用情况
        const disk = await this.getDiskUsage();

        // 进程信息
        const processInfo = await this.getProcessInfo();

        // 电池信息（如果可用）
        const battery = await this.getBatteryInfo();

        const metrics: SystemMetrics = {
            timestamp: Date.now(),
            cpu: {
                usage: cpuUsage,
                cores: os.cpus().length,
                loadAvg: os.loadavg()
            },
            memory: {
                total: totalMem,
                free: freeMem,
                used: usedMem,
                usage: memUsage
            },
            disk: {
                total: disk.total,
                free: disk.free,
                used: disk.total - disk.free,
                usage: ((disk.total - disk.free) / disk.total) * 100
            },
            processes: processInfo
        };

        // 添加电池信息（如果可用）
        if (battery) {
            metrics.battery = battery;
        }

        return metrics;
    }

    /**
     * 获取 CPU 使用率
     */
    private async getCpuUsage(): Promise<number> {
        return new Promise((resolve) => {
            const startUsage = process.cpuUsage();
            const startTime = process.hrtime();

            // 等待一小段时间来测量 CPU 使用率
            setTimeout(() => {
                const endUsage = process.cpuUsage(startUsage);
                const endTime = process.hrtime(startTime);

                const elapsedTime = endTime[0] * 1e9 + endTime[1]; // 纳秒
                const cpuTime = (endUsage.user + endUsage.system) * 1000; // 微秒转纳秒

                // 计算 CPU 使用率
                const cpuPercent = (cpuTime / elapsedTime) * 100 * os.cpus().length;
                resolve(Math.min(100, cpuPercent));
            }, 500);
        });
    }

    /**
     * 获取磁盘使用情况
     */
    private async getDiskUsage(): Promise<{ total: number; free: number }> {
        try {
            const path = process.platform === 'win32' ? 'c:' : '/';
            const disk = await diskusage.check(path);
            return {
                total: disk.total,
                free: disk.free
            };
        } catch (error) {
            logger.error('获取磁盘使用情况失败', { error });
            return {
                total: 0,
                free: 0
            };
        }
    }

    /**
     * 获取进程信息
     */
    private async getProcessInfo(): Promise<{ count: number; active: number; list?: Array<{ pid: number; name: string; cpu: number; memory: number }> }> {
        try {
            // 获取当前进程的 PID
            const pid = process.pid;

            // 获取进程使用情况
            const usage = await pidusage(pid);

            return {
                count: 1, // 只计算当前进程
                active: usage.cpu > 0 ? 1 : 0,
                list: [{
                    pid,
                    name: process.title || 'node',
                    cpu: usage.cpu,
                    memory: usage